package my.learn.common.web.core.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 自动化测试方法
 */
public class InterfaceAutomaticUnitTest {

    private static Logger log = LoggerFactory.getLogger(InterfaceAutomaticUnitTest.class);


    /**
     * 自动化测试
     *
     * @param bean 需要测试的对象
     */
    public static void run(Object bean) {
        run(bean, bean.getClass());
    }

    /**
     * 自动化测试
     *
     * @param bean      代理测试对象
     * @param beanClass 测试对象
     */
    public static <T> void run(Object bean, Class<?> beanClass) {

        final Method[] methods = beanClass.getDeclaredMethods();

        for (Method method : methods) {
            method.setAccessible(true);

            // 判断是否是构造方法
            final String name = method.getName();
            if ("$deserializeLambda$".equals(name) || name.equals(bean.getClass().getSimpleName())) {
                continue;
            }
            // 构建参数
            Type[] genericParameterTypes = method.getGenericParameterTypes();
            Object[] parameter = Arrays.stream(genericParameterTypes).map(type -> {

                if (ParameterizedType.class.isAssignableFrom(type.getClass())) {
                    ParameterizedType parameterizedType = (ParameterizedType) type;
                    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                    if (parameterizedType.getRawType().equals(List.class)) {
                        // list 第一个位置
                        return DataTransformUntil.simulationBeanList((Class<?>) actualTypeArguments[0], 10);
                    } else if (parameterizedType.getRawType().equals(Map.class)) {
                    }
                    return DataTransformUntil.simulationBean((Class<?>) parameterizedType.getRawType());

                } else if (Class.class.isAssignableFrom(type.getClass())) {
                    return DataTransformUntil.simulationBean((Class<?>) type);
                } else {
                    log.error("i can not analysis the method of param:{}", type.getTypeName());
                    return null;
                }
            }).toArray();
            Object invoke = null;
            try {
                invoke = method.invoke(bean, parameter);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            log.info("执行方法【{}#{}】,返回数据:：【{}】", bean.getClass().getName(), method.getName(), invoke);
        }

    }

}
